﻿using System;
using System.Text;

namespace BizElements.Core.ProviderComponents
{
    /// <summary>Renders and executes <see cref="UpdateStatement"/></summary>
    public interface IUpdater
    {
        #region Properties.

        /// <summary>Gets whether bulk updates are implemented/supported.</summary>
        bool ImplementsBulkUpdate { get; }

        #endregion

        #region Methods.

        /// <summary>Creates a <see cref="SelectStatement"/> that retrieves data that is to be updated. <b>null</b> if data dont't have to be fetched, ie. if bulk update is supported when using multiple tables.</summary>
        /// <param name="update">Update statement.</param>
        /// <param name="dbms">Target DBMS.</param>
        /// <param name="output">StringBuilder to which the SQL code is appended.</param>
        /// <param name="parameters">SQL parameter collection to which the object's and its children's parameters are added. After the rendering is done the collection contains all parameters with unique names.</param>
        void RenderSelect(UpdateStatement update, DbmsType dbms, StringBuilder output, DbParameterCollection parameters);

        /// <summary>Executes <see cref="UpdateStatement"/>.</summary>
        /// <param name="update">Update statement.</param>
        /// <param name="dbms">Target DBMS.</param>
        /// <param name="conn">Connection-transaction context to use.</param>
        /// <param name="lastExecutedCommandInfo">Output parameter: statistic for executed command.</param>
        /// <returns>The number of rows affected.</returns>
        int Execute(UpdateStatement update, DbmsType dbms, IConnectionProvider conn, out CommandExecutionStatistics lastExecutedCommandInfo);

        /// <summary>Renders UPDATE statement if it can be executed as a single statement. Does nothing if multiple atomic statements are required to execute the task.</summary>
        /// <param name="update">Update statement.</param>
        /// <param name="dbms">Target DBMS.</param>
        /// <param name="output">StringBuilder to which the SQL code is appended.</param>
        /// <param name="parameters">SQL parameter collection to which the object's and its children's parameters are added. After the rendering is done the collection contains all parameters with unique names.</param>
        void RenderUpdate(UpdateStatement update, DbmsType dbms, StringBuilder output, DbParameterCollection parameters);

        #endregion
    }           
}